
package com.hertz.alarm.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.InternalResourceView;
import org.springframework.web.servlet.view.json.MappingJacksonJsonView;

import com.hertz.alarm.controller.support.ResultModel;
import com.hertz.alarm.expection.MessageResolvableException;
import com.hertz.alarm.util.JsonMapperHelper;
import com.hertz.alarm.util.MapXMLConvert;
import com.hertz.alarm.util.ReturnCodeConstants;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.mapper.DefaultMapper;



@Controller
//@Loggable
public abstract class BaseController {
	///protected Logger logger;
	
	/*@Resource
	private ObjectMapper objectMapper;*/
	
	private final String MSG_PREFIX = "msg.str.";
    @Resource
    protected MessageSource messageSource;
	
	
	@Resource
    protected MappingJacksonJsonView jsonView;
	
	protected HttpSession getSession(HttpServletRequest request){
		return request.getSession(false);
	}
	
	
	protected ModelAndView returnErrorPage(HttpServletRequest request,String msgkey,Object...msgobjs) {
		Map<String,Object> paramMap = new HashMap<String, Object>();
		paramMap.put("msg",messageSource.getMessage(msgkey, msgobjs,Locale.CHINESE));
                
		return returnErrorPage(paramMap,request);
	}
	
	protected ModelAndView returnErrorPage(Map<String,Object> paramMap,HttpServletRequest request) {
		paramMap.put(ReturnCodeConstants.VIEW_NAME_STR, "/tip/error");
		return returnModelAndView(paramMap,request);
	}
	
	protected ModelAndView innerRedirect(String uri,Map<String,Object> paramMap,HttpServletRequest request,HttpServletResponse response) {
		try {
			String defaultExt = "jspf";
			String ext = StringUtils.getFilenameExtension(request.getRequestURI());
			if(ext != null){
				defaultExt = ext;
			}
			ext = StringUtils.getFilenameExtension(uri);
			if(ext != null){
				defaultExt = ext;
				uri = uri.replaceAll("."+ext,"");
			}
			
			InternalResourceView ss=new InternalResourceView(String.format("%s.%s",uri,defaultExt));
			ss.render(paramMap,request,response);
		} catch (Exception e) {
		}
		return null;
	}
	
	protected ModelAndView returnNoLogin(HttpServletRequest request,HttpServletResponse response) {
		String uri = request.getRequestURI();
		String ext = StringUtils.getFilenameExtension(uri);
		String redirectJsp = "/";
		try {
			if("json".equalsIgnoreCase(ext)){
				String msg = String.format("{\"%s\":%d , \"%s\":\"not_login\"}",ReturnCodeConstants.RETURN_CODE_STR,ReturnCodeConstants.NOT_LOGIN,ReturnCodeConstants.RETURN_MSG_STR);
				request.setAttribute("msg", msg);
				//response.setHeader("Content-Type", "application/json; charset=UTF-8");
				response.setContentType("application/json; charset=UTF-8");
				redirectJsp = "/msg.jsp";
				request.getRequestDispatcher(redirectJsp).forward(request, response);
				return null;
			}
			response.sendRedirect(redirectJsp);
		} catch (Exception e) {
			
		}
		return  null;
	}
	
	protected ModelAndView returnModelAndView(long ret,HttpServletRequest request) {
		if(ret<ReturnCodeConstants.SUCCESS){
			return createFailureModelAndView(ret,ReturnCodeConstants.RETURN_FAILURE_VALUE_STR,request);
		}
		return  createSuccessModelAndView(ret,ReturnCodeConstants.RETURN_SUCESS_VALUE_STR,request);
	}
	
	protected ModelAndView returnModelAndView(Object obj,HttpServletRequest request) {
		if(obj==null){
			return createFailureModelAndView(ReturnCodeConstants.FAILURE,ReturnCodeConstants.RETURN_FAILURE_VALUE_STR,request);
		}
		return  createSuccessModelAndView(obj,request);
	}
	
	protected ModelAndView returnModelAndView(Map<String,Object> data,HttpServletRequest request) {
		if(data==null || data.isEmpty()){
			data = data==null?new HashMap<String,Object>():data;
			if(!data.containsKey(ReturnCodeConstants.RETURN_CODE_STR))
				data.put(ReturnCodeConstants.RETURN_CODE_STR, ReturnCodeConstants.FAILURE);
	    	if(!data.containsKey(ReturnCodeConstants.RETURN_MSG_STR))
	    		data.put(ReturnCodeConstants.RETURN_MSG_STR, ReturnCodeConstants.RETURN_FAILURE_VALUE_STR);	
		}else{
			if(!data.containsKey(ReturnCodeConstants.RETURN_CODE_STR))
				data.put(ReturnCodeConstants.RETURN_CODE_STR, ReturnCodeConstants.SUCCESS);
	    	if(!data.containsKey(ReturnCodeConstants.RETURN_MSG_STR))
	    		data.put(ReturnCodeConstants.RETURN_MSG_STR, ReturnCodeConstants.RETURN_SUCESS_VALUE_STR);	
		}
		return  createModelAndView(data,request);
	}
	
	protected ModelAndView createFailureModelAndView(long returnCode,String returnMsg,HttpServletRequest request) {
		return createSimpleModelAndView(returnCode,returnMsg,request);
	}	
	
	protected ModelAndView createSuccessModelAndView(long returnCode,String returnMsg,HttpServletRequest request) {
		return createSimpleModelAndView(returnCode,returnMsg,request);
	}
	protected ModelAndView createSimpleModelAndView(long returnCode,String returnMsg,HttpServletRequest request) {
		Map<String,Object> map = new HashMap<String,Object>();   	   	
   	   	map.put(ReturnCodeConstants.RETURN_CODE_STR,returnCode);
   	   	map.put(ReturnCodeConstants.RETURN_MSG_STR,returnMsg);
    	return createModelAndView(map,request);
	}
    
    protected ModelAndView createSuccessModelAndView(Object data,HttpServletRequest request) {    	    	
   	   	Map<String,Object> map = new HashMap<String,Object>();
   	   	map.put("data", data);
    	return createSuccessModelAndView(map,request);
    }
    
    protected ModelAndView createSuccessModelAndView(Map<String,Object> data,HttpServletRequest request) {
    	if(!data.containsKey(ReturnCodeConstants.RETURN_CODE_STR))
    		data.put(ReturnCodeConstants.RETURN_CODE_STR, ReturnCodeConstants.SUCCESS);
    	if(!data.containsKey(ReturnCodeConstants.RETURN_MSG_STR))
    		data.put(ReturnCodeConstants.RETURN_MSG_STR, ReturnCodeConstants.RETURN_SUCESS_VALUE_STR);		
    	return createModelAndView(data,request);
    }
    protected ModelAndView createModelAndView(Map<String,Object> data,HttpServletRequest request) {
    	String ext = StringUtils.getFilenameExtension(request.getRequestURI());	
    	ModelAndView mv = null;
    	if("do".equalsIgnoreCase(ext)){
    		mv = new ModelAndView("/msg");
    		mv.addObject("msg", data);    		    		
    	}else if("xml".equalsIgnoreCase(ext)){
    		mv = new ModelAndView("/xml");
    		try {
				mv.addObject("data",createXML(data));
			} catch (Exception e) {
				e.printStackTrace();
				mv.addObject("data","<error>createXML error</error>");
			}
    	}else if("jsonp".equalsIgnoreCase(ext)){
    		mv = new ModelAndView("/jsonp");
    		try {
				mv.addObject("data",JsonMapperHelper.objectMapper.writeValueAsString(data));
			} catch (Exception e) {
				e.printStackTrace();
				mv.addObject("data","jackson.json error:"+e);
			}
    	}else if("jspf".equalsIgnoreCase(ext)){
    		//String filename = getViewName()!=null?getViewName():StringUtils.stripFilenameExtension(request.getRequestURI());
    		String filename = StringUtils.stripFilenameExtension(request.getRequestURI());
    		Object viewObj = data.get(ReturnCodeConstants.VIEW_NAME_STR);
    		if(viewObj != null){
    			filename = (String)viewObj;
    			//data.remove(WebConstants.VIEW_NAME_STR);
    		}
    		
    		mv = new ModelAndView(filename);    		
    		for(Map.Entry<String, Object> entity:data.entrySet()){
    	        mv.addObject(entity.getKey(), entity.getValue());    	    
    		}
    	}else{
    		mv = new ModelAndView(jsonView);    		
    	    for(Map.Entry<String, Object> entity:data.entrySet()){
    	        mv.addObject(entity.getKey(), entity.getValue());
    	    }	
    	}
    	String useragent = (String)request.getAttribute("useragent");
    	if(useragent != null && !useragent.equals("")){
    		mv.addObject("useragent",useragent);
    	}
        return mv;
    }
    
    private String createXML(Object data) throws JsonGenerationException, JsonMappingException, IOException{    	
    	Map<String,Object> map = null;
    	if(data!=null){
    		map = new HashMap<String,Object>();
    		map.put("data", data);
    	}
    	return createXML(map);
    }
    
    private String createXML(Map<String,Object> data) throws JsonGenerationException, JsonMappingException, IOException{
    	StringBuilder sb = new StringBuilder();  	
    	if(data!=null){
			XStream xstream = new XStream();
			xstream.registerConverter(new MapXMLConvert(new DefaultMapper(BaseController.class.getClassLoader())));						
			xstream.alias("result",Map.class);			
			sb.append(xstream.toXML(data));
		}
    	return sb.toString();
    }   
    
    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ModelAndView handleException(
            HttpServletRequest request, MessageResolvableException ex) {
        ModelAndView mv = new ModelAndView(jsonView);
        mv.addObject(ReturnCodeConstants.RETURN_CODE_STR, HttpStatus.BAD_REQUEST.value());
        mv.addObject(ReturnCodeConstants.RETURN_MSG_STR, messageSource.getMessage(
                ex.getKey(), ex.getArgs(), Locale.CHINESE));
        return mv;
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ModelAndView handleException(HttpServletRequest request,
            MissingServletRequestParameterException ex) {
        ModelAndView mv = new ModelAndView(jsonView);
        mv.addObject(ReturnCodeConstants.RETURN_CODE_STR, HttpStatus.BAD_REQUEST.value());
        mv.addObject(ReturnCodeConstants.RETURN_MSG_STR, ex.getMessage());
        return mv;
    }
    
    @ExceptionHandler
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ModelAndView handleException(HttpServletRequest request, Exception ex) {
        ex.printStackTrace();
        System.err.printf("URI:%s PARAMS:%s MESSAGE:%s", new Object[] {
            request.getRequestURI(), request.getQueryString(), ex.toString()
        });        
        return createFailureModelAndView(500,"fail",request);
    }
    
    public ResultModel<Object> buildResultModel(Object t){
    	if(t != null){
    		return new ResultModel<Object>(t, ReturnCodeConstants.SUCCESS,messageSource.getMessage(MSG_PREFIX + ReturnCodeConstants.SUCCESS, null,Locale.CHINESE));
    	}else{
    		return new ResultModel<Object>(t, ReturnCodeConstants.FAILURE,messageSource.getMessage(MSG_PREFIX + ReturnCodeConstants.FAILURE, null,Locale.CHINESE));
    	}
    }
    
    public ResultModel<Object> buildResultModel(Object t,int retCode,Object...msgobjs){
    	return new ResultModel<Object>(t, retCode,messageSource.getMessage(MSG_PREFIX + retCode, msgobjs,Locale.CHINESE));
    }
}